package cn.mifengkong.appcommon.customecamera;

import android.Manifest;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ImageView;

import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ImageViewTarget;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.mifengkong.frtools.glide.GlideApp;
import com.mifengkong.frtools.util.FRFileUtils;
import com.mifengkong.frtools.util.FRToast;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.mifengkong.appcommon.webview.BitmapSaveCallback;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;


/**
 * 图片工具类
 */
public class ImageUtils {

    //保存图片文件
    public static String saveToFile(String fileFolderStr, boolean isDir, Bitmap croppedImage) throws IOException {
        return saveToFile(fileFolderStr, isDir, croppedImage, 70);
    }

    //保存图片文件
    public static String saveToFile(String fileFolderStr, boolean isDir, Bitmap croppedImage, int quality) throws IOException {

        File jpgFile;
        if (isDir) {
            File fileFolder = new File(fileFolderStr);
            Date date = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
            String filename = format.format(date) + ".jpeg";//必须是这个格式，要不然服务端不接收
            if (!fileFolder.exists()) { // 如果目录不存在，则创建
                FRFileUtils.getInst().mkdir(fileFolder);
            }
            jpgFile = new File(fileFolder, filename);
        } else {
            jpgFile = new File(fileFolderStr);
            if (!jpgFile.getParentFile().exists()) { // 如果目录不存在，则创建
                FRFileUtils.getInst().mkdir(jpgFile.getParentFile());
            }
        }
        FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流

        croppedImage.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
        closeStream(outputStream);
        return jpgFile.getPath();
    }

    /**
     * 关闭流
     *
     * @param stream 可关闭的流
     */
    public static void closeStream(Closeable stream) {
        try {
            if (stream != null)
                stream.close();
        } catch (IOException e) {

        }
    }

    /**
     * 如果是前置摄像头的话，将拍出来的图片进行左右翻转
     *
     * @param bmp
     * @return
     */
    public static Bitmap convertBmp(Bitmap bmp) {
        return convertBmp(bmp, -90);
    }

    /**
     * 如果是前置摄像头的话，将拍出来的图片进行左右翻转
     *
     * @param bmp
     * @return
     */
    public static Bitmap convertBmp(Bitmap bmp, int rotate) {
        int w = bmp.getWidth();
        int h = bmp.getHeight();

        Matrix matrix = new Matrix();
        matrix.setRotate(rotate, w / 2, h / 2);
//        matrix.postScale(1, 1); // 镜像水平翻转
        Bitmap convertBmp = Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true);

        return convertBmp;
    }

    /**
     * @param bmp                获取的bitmap数据
     * @param bitmapSaveCallback
     */
    public static void saveBmp2Gallery(final Context context, final String imgPath,final Bitmap bmp, final BitmapSaveCallback bitmapSaveCallback) {
        final String picName = "saveBitmap-" + Long.toString(System.currentTimeMillis());
        final String[] fileName = {null};
        //系统相册目录
        final String galleryPath = Environment.getExternalStorageDirectory()
                + File.separator + Environment.DIRECTORY_DCIM
                + File.separator + "Camera" + File.separator;

        Observable.create(new ObservableOnSubscribe<File>() {
            @Override
            public void subscribe(ObservableEmitter<File> observableEmitter) throws Exception {
                // 声明文件对象
                File file = null;
                // 声明输出流
                FileOutputStream outStream = null;

                try {
                    // 如果有目标文件，直接获得文件对象，否则创建一个以filename为名称的文件
                    file = new File(galleryPath, picName + ".jpeg");

                    // 获得文件相对路径
                    fileName[0] = file.toString();
                    // 获得输出流，如果文件中有内容，追加内容
                    outStream = new FileOutputStream(fileName[0]);
                    if (null != outStream) {
                        bmp.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
                    }

                } catch (Exception e) {
                    e.getStackTrace();
                } finally {
                    try {
                        if (outStream != null) {
                            outStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                MediaStore.Images.Media.insertImage(context.getContentResolver(),
                        bmp, fileName[0], null);
                observableEmitter.onNext(file);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<File>() {
                    @Override
                    public void accept(File file) throws Exception {
                        Log.e("jiang", "accept:" + "一张图片下载完成");
                        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        Uri uri = Uri.fromFile(file);
                        intent.setData(uri);
                        context.sendBroadcast(intent);
                        if (bitmapSaveCallback != null) {
                            bitmapSaveCallback.onSuccess(file,imgPath);
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        FRToast.showToastSafe("当前图片下载失败");
                        if (bitmapSaveCallback != null) {
                            bitmapSaveCallback.onSuccess(null,imgPath);
                        }
                    }
                });


    }


    /**
     * 从网络中获取图片，并保存到相册
     *
     * @param context
     * @param imageUrls
     */
    public static void getBitmapForUrlAndSaveToAlbum(Context context, final String... imageUrls) {
        if (Build.VERSION.SDK_INT >= 23 && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
            FRToast.showToastSafe("应用缺少存储卡权限");
        } else {
            //添加权限判断
            if (imageUrls == null || imageUrls.length == 0) {
                return;
            }
            if (!(context instanceof Application)) {
                context = context.getApplicationContext();
            }
            List<String> imageUrlLists = Arrays.asList(imageUrls);
            Collections.reverse(imageUrlLists);
            //Arrays.asList转换成的list是不能执行remove，add等操作的，要不然会报异常。这里需要做转换
            List arrList = new ArrayList(imageUrlLists);
            getBitmapForUrlAndSaveToAlbum(context, arrList, null,null);
        }
    }

    /**
     * 从网络中获取图片，并保存到相册
     *
     * @param context
     * @param imageUrls
     */
    public static void getBitmapForUrlAndSaveToAlbum(Context context, LoanImgFinish loanImgFinish, final String... imageUrls) {
        Map<String, File> files = new HashMap<>();
        if (Build.VERSION.SDK_INT >= 23 && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
            FRToast.showToastSafe("应用缺少存储卡权限");
        } else {
            //添加权限判断
            if (imageUrls == null || imageUrls.length == 0) {
                return;
            }
            if (!(context instanceof Application)) {
                context = context.getApplicationContext();
            }
            List<String> imageUrlLists = Arrays.asList(imageUrls);
            Collections.reverse(imageUrlLists);
            //Arrays.asList转换成的list是不能执行remove，add等操作的，要不然会报异常。这里需要做转换
            List arrList = new ArrayList(imageUrlLists);
            getBitmapForUrlAndSaveToAlbum(context, arrList, loanImgFinish,files );
        }
    }

    /**
     * 从网络中获取图片，并保存到相册
     *
     * @param context
     * @param imageUrls
     */
    public static void getBitmapForUrlAndSaveToAlbum(final Context context, final List<String> imageUrls, final LoanImgFinish loanImgFinish, final Map files) {
        if (imageUrls == null || imageUrls.isEmpty()) {
            if (null != loanImgFinish) {
                loanImgFinish.loanFinish(files);
            }
            FRToast.showToastSafe("下载完成");
            return;
        }
        getBitmapForUrlAndSaveToAlbum(context, imageUrls.get(0), new BitmapSaveCallback() {
            @Override
            public void onSuccess(File file,String imgPath) {
                if (null != file && null != files && null != imgPath) {
                    files.put(imgPath, file);
                }
                imageUrls.remove(0);
                getBitmapForUrlAndSaveToAlbum(context, imageUrls, loanImgFinish, files);
            }
        });
    }

    public interface LoanImgFinish {
        void loanFinish(Map map);
    }


    /**
     * 从网络中获取图片，并保存到相册
     *
     * @param context
     * @param imageUrl
     */
    public static void getBitmapForUrlAndSaveToAlbum(final Context context, final String imageUrl, final BitmapSaveCallback bitmapSaveCallback) {
        if (TextUtils.isEmpty(imageUrl)) {
            return;
        }
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                GlideApp.with(context).load(imageUrl).apply(new RequestOptions()).into(new SimpleTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        ImageUtils.saveBmp2Gallery(context, imageUrl,((BitmapDrawable) resource).getBitmap(), bitmapSaveCallback);
                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        super.onLoadFailed(errorDrawable);

                    }
                });


            }
        });
    }

}
